package a_reassign;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import me.haui.plg.backingBean.sort.AlphanumComparator;
import me.haui.plg.backingBean.sort.SortierungComparator;
import me.haui.plg.entity.Auspraegung;
import me.haui.plg.entity.Leitfaden;
import me.haui.plg.entity.Rahmenbedingung;
import me.haui.plg.entity.RahmenbedingungUnterpunkt;


/**
 *
 * @author admin
 */
public class Word2003XMLDocumentReport {

    
    private StringBuilder documentString = null;
    
    
    private static final String authorString = "Prospect Unternehmensberatung GesmbH";
    
    
    private static final String nullString = "---";
    
    
    private Leitfaden leitfaden;
    
    
    public Word2003XMLDocumentReport(Leitfaden leitfaden){
        
        if (leitfaden == null){
            throw new IllegalArgumentException("You have to pass a Leitfaden object.");
        }
        
        this.leitfaden = leitfaden;
                    
    }
    
    
    private String getCleanData(String string){
        
        return string.replace("<", "&lt;").replace(">", "&gt;");
        
    }
    
    
    private void setHeadingOnFirstPage(){
        
        documentString.append( getTextInParagraphAndRun( this.leitfaden.getName(), true, 28 ) );
        
    }

    private String getTextInParagraphAndRun(String text
                                          , boolean bold
                                          , int specialTextSize
            ){

        return "\n"
                + "<w:p> \n"
                + getTextRun(text, bold, specialTextSize)
                + "</w:p>"
                + "\n";
        
    }
    
    
    private String getTextRun(String text, boolean bold, int specialTextSize){
        
        String boldOnOff = "";
        String textSize  = "";
        
        
        if (bold == true) {
            boldOnOff = "     <w:b w:val=\"on\"/> \n";
        }
        
        
        if (specialTextSize != 0) {
            textSize = " <!-- Special textsize --> \n"
                    + "  <w:sz w:val=\"" + specialTextSize + "\"/> \n";
        }
        
        
        return   "<w:r> \n"
                + "   <w:rPr> \n"
                + "   <!-- Make the text bold --> \n"
                + boldOnOff
                + textSize
                + "   </w:rPr> \n"
                + "<w:t>" + getCleanData(text) + "</w:t> \n"
                + "</w:r> \n";
        
    }
    
    
    private void setCRLF(int  repeatForTimes){
        
        for ( int i = 0; i < repeatForTimes; i++ ){
            documentString.append( getTextInParagraphAndRun("",false,0) );
        }
        
    }
    

    private String getStringTemplateChunk(String templateChunckName) throws IOException{

        //http://stackoverflow.com/questions/13242782/reading-a-text-file-in-war-archive
        //http://haveacafe.wordpress.com/2008/10/19/how-to-read-a-file-from-jar-and-war-files-java-and-webapp-archive/        
        InputStream inputStream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/resources/Word2003XMLDocumentChuncks/" + templateChunckName);
       
        InputStreamReader is = new InputStreamReader(inputStream);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(is);
        String read = bufferedReader.readLine();

        while(read != null) {
            //System.out.println(read);
            stringBuilder.append(read).append("\n");
            read =bufferedReader.readLine();
        }
        
        return stringBuilder.toString();

    }
    
    
    public String getFileAsString(){

        try {
            
            documentString = new StringBuilder( 
                    getStringTemplateChunk("Header.txt").
                    replace("<o:Author>$author$</o:Author>", "<o:Author>" + authorString + "</o:Author>").
                    replace("<o:LastAuthor>$LastAuthor$</o:LastAuthor>", "<o:LastAuthor>" + authorString + "</o:LastAuthor>").
                    replace("<o:Company>$Company$</o:Company>", "<o:Company>" + authorString + "</o:Company>").
                    replace("<o:Title>$Titel$</o:Title>", "<o:Title>" + getCleanData(this.leitfaden.getName()) + "</o:Title>")
                    );
            
        } catch (IOException ex) {
            
            Logger.getLogger(Word2003XMLDocumentReport.class.getName()).log(Level.SEVERE, null, ex);
            
            documentString = new StringBuilder();
            
            documentString.append("Leider ist bei der Erstellung der Datei ein Fahler aufgetreten."
                    + "Bitte benachrichtigen Sie den Support");
            
            return documentString.toString();
            
        }

        setHeadingOnFirstPage();
        
        setCRLF(1);
        
        setBeschreibung();
        
        setCRLF(1);
        
        setAllRahmenBedingungen();
        

        
        return documentString.toString() + " \n"
                + "<!-- Setting page orientation -->"
                + "<w:sectPr wsp:rsidR=\"001654F4\" wsp:rsidSect=\"000B1B26\"> "
                + "<w:pgSz w:w=\"16838\" w:h=\"11906\" w:orient=\"landscape\" /> "

                + "</w:sectPr> \n"
                + "\n"
                + "</w:body> \n"
                + "</w:wordDocument>";
        
    }

    private void setBeschreibung() {
        
        documentString.append( getTextInParagraphAndRun( this.leitfaden.getBeschreibung(),false,0 ) );        
        
    }

    private void setAllRahmenBedingungen() {
        
        List<Rahmenbedingung>  rahmenbedingungCollection = (List<Rahmenbedingung>) this.leitfaden.getRahmenbedingungCollection();
        

        //http://tutorials.jenkov.com/java-collections/sorting.html
        //Jedoch ohne generische Angabe bei selbst erstellter Klasse
        //http://www.programmersbase.net/Content/Java/Content/Tutorial/Java/Interface.htm
                
        Collections.sort(rahmenbedingungCollection, new SortierungComparator());        
        
        for ( Rahmenbedingung r : rahmenbedingungCollection ){
            
            setCRLF(2);
            
            setRahmenbedingung(r);
            
        }
        
    }

    private void setRahmenbedingung(Rahmenbedingung r) {
        
        documentString.append( getTextInParagraphAndRun( r.getKurzbezeichnung(),true,0 ) );
        
        setCRLF(1);
        
        documentString.append( getTextInParagraphAndRun( r.getName(),false,0 ) );
        
        setCRLF(1);
        
        setRahmenbedingungUnterpunkteTable(r);
        
    }

    
    private void setRahmenbedingungUnterpunkteTable(Rahmenbedingung r) {

        
        List<RahmenbedingungUnterpunkt>  rahmenbedUnterPunktList = (List<RahmenbedingungUnterpunkt>) r.getRahmenbedingungUnterpunktCollection();
                
        boolean firstRahmenbedingungUnterpunkteRow = true;

        
        if (rahmenbedUnterPunktList.isEmpty() == false){
        
            //Haui hier später wenn auf Sortierung umgestellt
            //ebenfalls umstellen.
            Collections.sort(rahmenbedUnterPunktList, new AlphanumComparator());
            
            
            try {
                
                documentString.append( getStringTemplateChunk("RahmenbedingungUnterpunkteTableHeader.txt")
                        .replace("$ru.kurzbezeichnung$", r.getKurzbezeichnung())
                        );                
                
            } catch (IOException ex) {
                Logger.getLogger(Word2003XMLDocumentReport.class.getName()).log(Level.SEVERE, null, ex);
            }
                        
                        



            Iterator<RahmenbedingungUnterpunkt> ruIterator = rahmenbedUnterPunktList.iterator();

            firstRahmenbedingungUnterpunkteRow = true;

            
            //Cycle over Rahmenbedingungunterpunkt
            while ( ruIterator.hasNext() ) {

                RahmenbedingungUnterpunkt ru = ruIterator.next();
                                
                        try {

                            documentString.append( getRahmenbedingungUnterpunkteTableRow( ru ) );
                            firstRahmenbedingungUnterpunkteRow = false;

                        } catch (IOException ex) {        
                            Logger.getLogger(Word2003XMLDocumentReport.class.getName()).log(Level.SEVERE, null, ex);
                        }                    

                    }

            
            documentString.append("</w:tbl>");            

            setCRLF(2);
            
        }

        
    }
    
    
    

    
    private String getRahmenbedingungUnterpunkteTableRow(RahmenbedingungUnterpunkt ru) throws IOException{

      boolean firstRowInASeries = true;
      

      
      StringBuilder returnString = new StringBuilder();
      
        //Add Auspraegungen
        List<Auspraegung>  auspraegungList = (List<Auspraegung>) ru.getAuspraegungCollection();
        //Haui hier später wenn auf Sortierung umgestellt
        //ebenfalls umstellen.
        Collections.sort(auspraegungList, new AlphanumComparator());

        //Cycle over Auspraegung
        Iterator<Auspraegung> auspraegungIterator = auspraegungList.iterator();

        //We know there is not even one Ausprägung assigned.
        if ( auspraegungIterator.hasNext() == false ){
         
            returnString.append(getStringTemplateChunk("RahmenbedingungUnterpunkteTableRow.txt")
                     //Hier noch eine ganze Leerzeile einfügen
                    .replace("$ru.name$", ru.getName() )
                    .replace("$ru.beschreibung$", ru.getBeschreibung() )
                    .replace("$vMergeVal$", "restart")
                    .replace("$auspraegung.name$",nullString)
                    .replace("$auspraegung.beschreibung$",nullString)
                    .replace("$auspraegung.erklaerung$",nullString)                                                
                    );            
            
        }
        
        while ( auspraegungIterator.hasNext() ) {

            Auspraegung a = auspraegungIterator.next();

            if ( firstRowInASeries == true ){
            
                returnString.append(getStringTemplateChunk("RahmenbedingungUnterpunkteTableRow.txt")
                        .replace("$ru.name$", ru.getName() )
                        .replace("$ru.beschreibung$", ru.getBeschreibung() )
                        .replace("$vMergeVal$", "restart")
                        .replace("$auspraegung.name$", replaceNullContent( a.getName()) )
                        .replace("$auspraegung.beschreibung$", replaceNullContent( a.getBeschreibung()) )
                        .replace("$auspraegung.erklaerung$", replaceNullContent( a.getErlaeuterung()) )
                        );
                
            }else{

                returnString.append(getStringTemplateChunk("RahmenbedingungUnterpunkteTableRow.txt")
                        .replace("$ru.name$", ru.getName() )
                        .replace("$ru.beschreibung$", ru.getBeschreibung() )
                        .replace("$vMergeVal$", "continue")
                        .replace("$auspraegung.name$", replaceNullContent( a.getName()) )
                        .replace("$auspraegung.beschreibung$", replaceNullContent( a.getBeschreibung()) )
                        .replace("$auspraegung.erklaerung$", replaceNullContent( a.getErlaeuterung()) )
                        );
                
            }
            
            firstRowInASeries = false;
            
        }
      
      return returnString.toString();
    
    } 

    
    private static String replaceNullContent(String content){
        
        if (content.replace(" ", "").isEmpty() == true ){
            return nullString;
        }
        
        return content;
        
    }
    
    
}

